
package hasthi.wsdm.capabilities;

import static hasthi.common.constants.WSDMConstants.EXTREME_MANAGEMENT_NS;
import static hasthi.common.constants.WSDMConstants.SERVICE_NAME;
import hasthi.common.HasthiException;
import hasthi.common.XmlBeanUtils;
import hasthi.common.HasthiException.FaultCode;
import hasthi.common.constants.HasthiConstants;
import hasthi.config.PropertyType;
import hasthi.wsdm.Capability;
import hasthi.wsdm.CapabilityDescription;
import hasthi.wsdm.ManagableResource;
import hasthi.wsdm.ManagedSystemHandle;
import hasthi.wsdm.ManagementAgentContext;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.w3.x2005.x08.addressing.EndpointReferenceType;

import wsdm.muws.ComponentAddressType;
import wsdm.muws.ComponentType;
import wsdm.muws.ManagementEventDocument;
import wsdm.muws.ManagementEventType;

public abstract class AbstractCapability implements Capability{
    protected static Log log = LogFactory.getLog(HasthiConstants.AGENT_LOGGER_NAME);
    protected CapabilityDescription capabilityDescription;
    //protected HashMap<QName, Object> propertiesMap = new HashMap<QName, Object>();
    protected ManagableResource ownedResource;
    protected ManagementAgentContext context;
    
    public void init(ManagementAgentContext context,ManagableResource ownedResource,CapabilityDescription description) throws HasthiException{
        this.context = context;
//        this.systemHandle = context.getManagedSystemHandle();
  //      Map<QName,Object> properties = systemHandle.getProperties();
        this.capabilityDescription = description;
        
        this.ownedResource = ownedResource;
        
//        PropertyType[] propertiesList = capabilityDescription.getCapabilityConfig().getPropertyArray();
//        for(PropertyType property:propertiesList){
//            QName name = property.getName();
//            Object value = properties.get(name);
//            if(value != null){
//                propertiesMap.put(name, value);
//            }
//        }
    }

    
    public CapabilityDescription getCapabilityDescription() {
        return capabilityDescription;
    }

//    public Object getProperty(QName name) throws HasthiException {
//        //return propertiesMap.get(name);
//    }
//
//    public void setProperty(QName name, Object value) throws HasthiException {
//        throw new HasthiException("Unsupported property "+name + " set in capability "+ this,FaultCode.InvaliedLocalArgumnet);
//    }
    
    protected  ManagementEventDocument createBaseEvent(Calendar currentTime) throws HasthiException{
        ManagementEventDocument eventDocument = ManagementEventDocument.Factory.newInstance();
        ManagementEventType eventType = eventDocument.addNewManagementEvent();
        eventType.setReportTime(currentTime);
        ComponentType sourceComponent = eventType.addNewSourceComponent();
        
        QName serviceName = ownedResource.getName();
        
        sourceComponent.setResourceId(serviceName.getNamespaceURI() + "/" + serviceName.getLocalPart());
        EndpointReferenceType epr = ownedResource.getResourceEndpointEPR();
        
        XmlCursor c = epr.addNewReferenceParameters().newCursor();
        c.toFirstContentToken();
        XmlBeanUtils.addNameValuePair(c, new QName(EXTREME_MANAGEMENT_NS,SERVICE_NAME), serviceName.getLocalPart());
        c.dispose();
        ComponentAddressType componentAddress = sourceComponent.addNewComponentAddress();
        XmlBeanUtils.addTypeAsChild(componentAddress, epr);
        return eventDocument;
    }
    
    public void sendEvent(XmlObject eventData) throws HasthiException{
        ownedResource.sendEvent(eventData);
    }


    public void parentResourceInitialized() {}


    @Override
    public String toString() {
        return capabilityDescription.getCapabilityConfig().getName();
    }

    public void stop() {}
}

